1、 input 子系统
	input 子系统用于管理各种输入设备，如按键、键盘、鼠标、触摸屏等，input 子系统分为3层：
	输入设备驱动层：包含各种各样的输入设备驱动程序，用于驱动输入设备，它是输入设备驱动程序开发需要关注的重点
	input 核心层：承上起下，用于管理输入设备驱动程序和输入事件处理程序，并提供驱动层和事件处理层的相互匹配和
通信的功能
	输入事件处理层：包含各种各样的输入事件处理程序，用于对输入设备的硬件进行了抽象，以便应用层能更方便的和输
入设备进行交互，其中 evdev 是一个通用输入事件驱动，它能与所有输入设备进行匹配，对于鼠标、键盘、触摸屏等常用
设备内核中已有相应的输入事件驱动程序
	注意：输入设备和输入事件驱动是多对多的关系，即一个输入设备可能有多个输入事件处理程序，一个输入事件处理程
序也可能有多个输入设备
2、 struct input_dev 对象
	input_dev 对象表示一个 input 设备，它的核心成员如下：
	//输入设备的名字
	const char *name;
	//在系统层次结构中设备的物理路径
	const char *phys;
	//设备的唯一识别码
	const char *uniq;
	//设备ID，包含总线类型、作者、产品和版本相关消息，它用于输入设备和事件处理程序间的匹配
	struct input_id id;
	//设备属性位图
	unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
	//输入设备支持的事件类型位图
	unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
	//相应事件可以上报的事件码位图
	//按键事件
	unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
	//相对坐标事件
	unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
	//绝对坐标事件
	unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
	//其他事件
	unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
	//led事件
	unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
	//声音事件
	unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
	//压力反馈事件
	unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
	//压力状态事件
	unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
	//触摸屏相关
	struct input_mt *mt;
	//操作函数，一般由事件处理程序调用，如 evdev 则是通过向应用层开放的字符设备驱动调用
	int (*open)(struct input_dev *dev);
	void (*close)(struct input_dev *dev);
	int (*flush)(struct input_dev *dev, struct file *file);
	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
	//input_handle 链表， Linux 通过 input_handle 对象关联输入设备和输入事件处理程序
	struct list_head h_list;
	事件码、事件类型、设备属性定义参考 input_event_codes.h 文件，可以通过 void __set_bit (int nr, volatile 
void *addr) 分别设置位图中的某一位，也可以使用 void input_set_capability(struct input_dev *dev, unsigned int
type, unsigned int code) 函数完成事件码位图和事件类型位图的设置。
	当设备支持重复事件后内核会为其开启一个定时器生成重复事件，无需设备驱动层重复上报。
3、注册和注销输入设备
	注册输入设备：
		1）分配输入设备； struct input_dev *input_allocate_device(void)
		2）初始化 input_dev 对象，主要是支持的事件类型和对应的事件码
		3）注册输入设备； int input_register_device(struct input_dev *dev)
	注销输入设备：
		1）注销输入设备； void input_unregister_device(struct input_dev *dev)
		2）释放输入设备； void input_free_device(struct input_dev *dev)
4、 struct input_handler
	input_handler 对象表示一个输入事件处理程序，其核心成员如下：
	//事件处理函数，用于处理输入设备上报的事件
	void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
	//事件处理函数，用于处理输入设备上报的事件，可处理多个事件，未定义时系统默认使用event实现
	void (*events)(struct input_handle *handle, const struct input_value *vals, unsigned int count);
	//事件过滤函数，用于处理输入设备上报的事件
	bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
	//自定义匹配函数，当系统匹配函数执行成功后才会调用此函数
	bool (*match)(struct input_handler *handler, struct input_dev *dev);
	//用于建立事件处理程序和输入设备的联系，通过调用 input_register_handle 实现
	int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
	//用于断开事件处理程序和输入设备的联系，通过调用 input_unregister_handle 实现
	void (*disconnect)(struct input_handle *handle);
	//事件处理程序和输入设备建立联系后执行
	void (*start)(struct input_handle *handle);
	//名字
	const char *name;
	//设备匹配表，用于与输入设备匹配
	const struct input_device_id *id_table;
	//input_handle 链表， Linux 通过 input_handle 对象关联输入设备和输入事件处理程序
	struct list_head h_list;
5、注册和注销输入事件处理程序
	注册输入事件处理程序
		1）初始化 input_handler 对象
		2）使用 input_register_handler 注册输入事件处理程序
	注销输入事件处理程序
		1）使用 input_unregister_handler 注销输入事件处理程序
6、 struct input_handle 对象
	input_handle 用于关联输入设备和事件处理程序
	//关联的输入设备
	struct input_dev *dev;
	//关联的事件处理程序
	struct input_handler *handler;
7、建立或断开输入设备和输入事件处理程序的联系
	建立输入设备和输入事件处理程序的联系：
		1）在注册输入设备驱动时会遍历 input_handler 并调用 input_attach_handler 进行输入设备驱动和输入事件处
	理程序的匹配，同样注册输入事件处理程序时也会遍历 input_dev 并调用 input_attach_handler 进行输入设备驱动
	程序和输入事件处理程序的匹配（利用输入设备驱动的 id 和输入事件处理程序的 id_table 进行匹配）。
		2）默认匹配函数执行成功后会调用事件处理程序提供的 match 函数
		3）匹配完成后会调用事件处理程序提供 connect 函数
		4）在 connect 函数分配并初始化 input_handle 对象（这里需要对输入设备驱动进行一次 get 操作）
		5）使用 input_register_handle 建立输入设备和输入事件处理程序的联系
	断开输入设备和输入事件处理程序的联系
		1）当注销输入设备驱动程序或输入事件处理程序时会遍历其 h_list （管理的 input_handle 对象）链表，执行
	输入事件处理程序的 disconnect 函数
		2）在 disconnect 函数使用 input_unregister_handle 断开输入设备和输入事件处理程序的联系（这里需要对输
	入设备驱动进行一次 put 操作）
8、输入设备上报事件
	通过函数 input_event 可以上报输入设备产生的输入事件：
		/**
		 * dev 需要上报的 input_dev。
		 * type 上报的事件类型，比如 EV_KEY。
		 * code 事件码，如 KEY_0、 KEY_1 等等。
		 * value 事件值，如按键事件 1 表示按键按下， 0 表示按键松开。
		 */
		void input_event(struct input_dev *dev,unsigned int type,unsigned int code,int value)
	另外针对常见类型的事件还有专门的事件上报函数，这些函数都是通过 input_event 函数进行了二次封装实现，如
input_report_key 可用于上报按键事件
9、事件同步
	输入设备事件上报完成后需要调用 input_sync 告诉内核此次上报结束：
		/**
		* 需要上报同步事件的 input_dev。
		*/
		void input_sync(struct input_dev *dev)
10、输入事件处理程序下发事件
	输入事件处理程序可以通过 input_inject_event 下发事件给输入设备，如 evdev 驱动在 connect 中注册了一个字符
设备，并在字符设备的 write中调用了此函数，使得应用层可以向输入设备驱动程序发送事件。
		/**
		 * handle 需要下发事件的 input_handle （在 input_handle 关联了事件处理程序和输入设备）
		 * type 下发的事件类型
		 * code 事件码
		 * value 事件值
		 */
		void input_inject_event(struct input_handle *handle,
			unsigned int type, unsigned int code, int value)
